/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package BitlyAlgo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 *
 * @author Demon
 */
public class Shortener {

    /**
     * 
     */
    public ArrayList<Long> array;
    Map<Integer, String> map;
    public String shortestURL;

    /**
     *
     */
    public Shortener() {
        this.array = new ArrayList<Long>();
        map = new HashMap<Integer, String>();
        initMap();
    }

    private void initMap() {
        map.put(0, "a");
        map.put(1, "b");
        map.put(2, "c");
        map.put(3, "d");
        map.put(4, "e");
        map.put(5, "f");
        map.put(6, "g");
        map.put(7, "h");
        map.put(8, "i");
        map.put(9, "j");
        map.put(10, "k");
        map.put(11, "l");
        map.put(12, "m");
        map.put(13, "n");
        map.put(14, "o");
        map.put(15, "p");
        map.put(16, "q");
        map.put(17, "r");
        map.put(18, "s");
        map.put(19, "t");
        map.put(20, "u");
        map.put(21, "v");
        map.put(22, "x");
        map.put(23, "y");
        map.put(24, "w");
        map.put(25, "z");

        map.put(26, "A");
        map.put(27, "B");
        map.put(28, "C");
        map.put(29, "D");
        map.put(30, "E");
        map.put(31, "F");
        map.put(32, "G");
        map.put(33, "H");
        map.put(34, "I");
        map.put(35, "J");
        map.put(36, "K");
        map.put(37, "L");
        map.put(38, "M");
        map.put(39, "N");
        map.put(40, "O");
        map.put(41, "P");
        map.put(42, "Q");
        map.put(43, "R");
        map.put(44, "S");
        map.put(45, "T");
        map.put(46, "U");
        map.put(47, "V");
        map.put(48, "X");
        map.put(49, "Y");
        map.put(50, "W");
        map.put(51, "Z");

        map.put(52, "0");
        map.put(53, "1");
        map.put(54, "2");
        map.put(55, "3");
        map.put(56, "4");
        map.put(57, "5");
        map.put(58, "6");
        map.put(59, "7");
        map.put(60, "8");
        map.put(61, "9");


    }

    /**
     *
     * @param number
     */

    public void compress(Long number) {

        while (number > 0) {
            Long remainder = number % 62;
            array.add(remainder);
            number /= 62;
        }

        //Reverse
       
        array = reverseArray(array);

    }

    /**
     *
     */

    public void match() {
        StringBuilder str = new StringBuilder();
        for (long x : array) {
            str.append(map.get((int) x));
        }
        shortestURL = str.toString();

    }

    /**
     *
     * @param url
     * @return
     */

    public Long decompress(String url){

        ArrayList<Long> tmpArray = auxDecompress(url);
        Long result  = 0L;
        for(int i = 0, j=tmpArray.size()-1; i < tmpArray.size(); i++, j--){
            result += (tmpArray.get(i)*(long)Math.pow(62, j));
        }
        
        return result;
    }

    /**
     *
     * @param url
     * @return
     */

    public ArrayList<Long> auxDecompress(String url) {

        Set<Integer> lst = map.keySet();
        ArrayList<Long> result = new ArrayList<Long>();
        for (int i = 0; i < url.length(); i++) {
            String c = Character.toString(url.charAt(i));

            if (map.containsValue(c)) {
                for (int x : lst) {
                    String tmp = map.get(x);
                    if (tmp.equals(c)) {
                        result.add((long) x);
                    }
                }
            }
        }
        return result;
    }

    /**
     *
     * @param al
     */

    public void printArray(ArrayList<Long> al) {
        for (Long l : al) {
            System.out.print(l + ",");
        }

        System.out.println();
    }

    /**
     *
     * @param arr
     * @return
     */
    private ArrayList<Long> reverseArray(ArrayList<Long> arr){
        
        ArrayList<Long> tmp = new ArrayList<Long>();
        for (int i = arr.size()-1; i >= 0; i--) {
            tmp.add(arr.get(i));
        }
        return tmp;
    }
}
